# -*- coding: UTF-8 -*-
import asyncio
import websockets
from threading import Lock, Thread
import json
import time
import pymongo
from datetime import datetime

class WsServer():
    def __init__(self,server="0.0.0.0",port=1235,logger=None,mongo_client=None):
        self.server = server
        self.port = port
        # 当前网页连接实例
        self._webclients = []
        self.logger = logger
        self._client_thread = None
        self.db = mongo_client['okex_trade']
         # 持仓张数表
        self.table_position = self.db['position']
        self.table_spots_depth = self.db['spots_depth']
        self.table_swap_depth = self.db['swap_depth']
        self.table_futures_depth = self.db['futures_depth']

    def msg_response(self,msg): # 推送消息给到 web客户端
        return
        if msg != None:
            for c in self._webclients:
                try:
                    loop = asyncio.new_event_loop()
                    asyncio.set_event_loop(loop)
                    loop.run_until_complete(c.send(json.dumps(msg)))
                    loop.close()
                except :
                    self._webclients.remove(c)
                    print("!!! TIMEOUT 1 !!!")
                    try:
                        loop = asyncio.new_event_loop()
                        asyncio.set_event_loop(loop)
                        loop.run_until_complete(c.close())
                        loop.close()
                    except:
                        print("!!! TIMEOUT 2 !!!")

    async def handle_message(self,websocket, path):
        self.logger.info("新的web连接进入：{0}".format(path));
        self._webclients.append(websocket)
        while True:
            try:
                msg = await websocket.recv()
                params = json.loads(msg)
                self.logger.info(params)
                symbol = "BTC"
                if 'symbol' in params:
                    symbol = params['symbol']
                fromType = "spot"
                if 'fromType' in params:
                    fromType = params['fromType']
                toType = "next_week"
                if 'toType' in params:
                    toType = params['toType']
                last_time = int(time.time())
                if 'last_time' in params:
                    last_time = int(params['last_time'])
                per_time = 5 # 5min
                if 'per_time' in params:
                    per_time = int(params['per_time'])
                if per_time <= 0 :
                    per_time = 5
                per_time = per_time * 60
                start_time = last_time - per_time # 最近4h数据
                query = {'time':{'$lt': last_time,'$gt': start_time},'symbol':symbol}
                timeData = []
                timeIndex = {}
                xhData = []
                jcData = []
                qhData = []
                i = 0
                while start_time <= last_time:
                    left = start_time % per_time
                    index = start_time - left
                    timeIndex["{0}".format(index)] = i
                    tl = time.localtime(index)
                    format_time = time.strftime("%Y/%m/%d %H:%M:%S", tl) 
                    timeData.append(format_time)
                    start_time += per_time
                    i = i+1
                for i in range(len(timeData)):
                    xhData.append(0)
                    qhData.append(0)
                    jcData.append(0)
                results = self.table_spots_depth.find(query)
                l = {}
                for result in results:
                    # 以5分钟数据为准 300s 取平均值
                    left = result['time'] % per_time
                    index = "{0}".format(result['time'] - left)
                    if index in l: #现货取最高买价 bids
                        l[index] = ( float(l[index])+float(result['bids'][0][0]) ) / 2
                    else :
                        l[index] = float(result['bids'][0][0])
                    if index not in timeIndex:
                        continue
                    xhData[timeIndex[index]] = l[index]
                results = self.table_position.find(query) # 持仓
                position = {}
                self.logger.info(query)
                for result in results:
                    # 以5分钟数据为准 300s 取平均值
                    left = result['time'] % per_time
                    index = "{0}".format(result['time'] - left)
                    if index in position: #持仓量
                        position[index] = ( float(position[index])+float(result['amount']) ) / 2
                    else :
                        position[index] = float(result['amount'])
                query['contractType'] = toType
                self.logger.info(query)
                results = self.table_futures_depth.find(query)
                fl = {}
                for result in results:
                    # 以5分钟数据为准 300s 取平均值
                    left = result['time'] % per_time
                    index = "{0}".format(result['time'] - left)
                    if index in fl: #期货取最低卖价 asks
                        fl[index] = ( float(fl[index])+float(result['asks'][0][0]) ) / 2
                    else :
                        fl[index] = float(result['asks'][0][0])
                    if index not in timeIndex:
                        continue
                    qhData[timeIndex[index]] = fl[index]
                    jcData[timeIndex[index]] = qhData[timeIndex[index]] - xhData[timeIndex[index]]
                sdata = {"timeData":timeData,"xhData":xhData,"qhData":qhData,"jcData":jcData}
                await websocket.send(json.dumps(sdata))
            except Exception as err:
                print("!!! SEND TIMEOUT 2 !!!",err)
                self._webclients.remove(websocket)
 
    async def run(self):
        self.logger.info("start ws server {0}:{1}".format(self.server,self.port))
        return await websockets.serve(self.handle_message, self.server, self.port)

